package com.atguigu.mybatis.demo;

import com.atguigu.mybatis.beans.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * Created by Smexy on 2023/3/22
 * <p>
 * 查询1号员工
 * <p>
 * Mybaits的设计思想:
 * ①sql语句 是编写在一个专门的文件中，和java源代码文件区别
 * ②在java源代码文件中引入要使用的sql
 * ③传统的jdbc套路模版已经帮你封装了，无需再编写，直接调用mybaits封装好的方法即可
 * <p>
 * ---------------------------
 * 入口还是先创建连接。
 * <p>
 * 连接：
 * JDBC:   Connection
 * Mybatis: SqlSession (sql会话)
 * <p>
 * -------------------------
 * 常见的创建对象的方式。
 * <p>
 * 构造器是public的，可以直接new
 * <p>
 * 在某些情况下，构造器不是public，是default,private,protected，无法直接new！
 * 框架会提供设计模式供你使用。
 * <p>
 * Phone a = new Phone();
 * <p>
 * 工厂模式:  Phone a = new PhoneFactory().getPhone();
 * <p>
 * 建造者模式:  Phone a = new PhoneBuilder().setCPU(100).setGpu(100).setRam(200G).build();
 * <p>
 * ----------------
 * 查询已经运行了
 * A query was run
 * and no Result Maps were found for the Mapped Statement 'feichangbang.sql1'.
 * 不知道查询的结果如何映射为 Java对象。
 * <p>
 * <p>
 * -------------------------------
 * 属性的封装规则:
 * 流程:
 * ①通过语句的id，及传入的参数生成最终的sql
 * selectOne("feichangbang.sql1", 1)
 * <p>
 * select * from employee where id = 1;
 * <p>
 * ②将sql发送给mysql服务器，获取查询结果
 * id  last_name  gender  email
 * ------  ---------  ------  -------------
 * 1  Tom        male    Tom@163.com
 * <p>
 * ③根据sql语句标签上，编写的  resultType="com.atguigu.mybatis.beans.Employee"
 * 将查询结果的一行，封装为一个 Employee。
 * <p>
 * 根据resultType的全类名使用反射，new Employee();
 * <p>
 * Employee e new Employee();
 * <p>
 * ④为属性赋值
 * 赋值的规则：   e.setXxx( 列值 )
 * Xxx： 查询的列名
 * e.setId(1);
 * e.setLast_name(Tom);
 * ...
 * <p>
 * -----------------------
 * 解决思路:
 * ①提供  setLast_name()
 * <p>
 * ②希望 mybatis自动把   last_name  转换为  lastName
 * 在配置中配置
 * <p>
 * -------------------------
 * shitt 两下： 搜索界面。搜类名。
 * ctrl + H: 查看类之间的继承关系
 * <p>
 * <p>
 * ----------------------
 * 使用SqlSession提供的方法的弊端：
 * ①不灵活
 * ②在某些方法的参数类型上没有校验。
 * 编译时，不会报错，运行可能出异常
 * <p>
 * 解决： 自己去编写Dao，在Dao(Mapper)中声明方法。
 */
public class HelloWorld
{
    public static void main(String[] args) throws IOException {

        //创建 SqlSessionFactory(根据配置文件创建)
        String resource = "mybatisconfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //获取一个SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*
            调用方法查询
             <T> T selectOne(String statement, Object parameter)
                    statement: sql语句的完整路径( namespace.id )

                    方法名的返回值前，编写了<x>,调用方法时，需要在方法名前声明泛型。

         */
        Employee employee = sqlSession.<Employee>selectOne("feichangbang.sql1", 1);

        //Employee employee = (Employee) o;

        System.out.println(employee);


    }
}
